#pragma once    
#include <iostream>
#include <string>
#include <vector>

// 套接字四件套
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "InetAddr.hpp"
#include "Log.hpp"
#include "Common.hpp"

// 创建一个socket类，用于创建socket连接

using namespace std;
using namespace log;

#define EXIT(x) exit(x)

class Socket
{
public:
    virtual void Init() = 0;                    // 初始化套接
    virtual void Bind() = 0;                    // 绑定地址
    virtual void Recev(string &getdata) = 0;    // 接收数据
    virtual void Accept() = 0;                  // 接收连接
    virtual void Send(string data) = 0;         // 发送数据
    virtual void Close(int fd) = 0;             // 关闭文件描述符
    virtual int Cur_rclientfd() = 0;               // 获取当前连接的文件描述符
    virtual int Socket_fd() = 0;                  // 获取套接字文件描述符
    void Create()
    {
        Init();
        Bind();
    }

};


// TCP Socket
class Socket_tcp : public Socket
{
public:
    Socket_tcp(uint16_t port = gdefault_port) : _server(port), _port(port),current_client_fd(-1)
    {
    }

    virtual void Init() override
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_sockfd < 0)
        {
            LOG(LogLevel::FATAL) << "创建套接字文件失败";
            END(-1);
        }
    }

    virtual void Bind() override
    {
        int n = bind(_sockfd, _server.NetAddr(), _server.NetAddrLen());
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "绑定失败";
            END(-1);
        }
        n = listen(_sockfd, Backblock);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "监听失败";
            END(-1);
        }
    }

    virtual void Accept() override
    {
        sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        current_client_fd = accept(_sockfd, CONV(&client_addr), &client_len);
        InterAddr client_addr_obj(client_addr);
        cout << "客户端地址：" << client_addr_obj.Ip() << ":" << client_addr_obj.Port() << endl;
        if (current_client_fd < 0)
        {
            LOG(LogLevel::ERROR) << "接收失败";
        }
    }

    virtual void Recev(string &getdata) override
    {
        if(current_client_fd<0)
        {
            LOG(LogLevel::ERROR) << "未连接客户端";
            return;
        }
        char buffer[1024*24];
        int n = recv(current_client_fd,buffer, sizeof(buffer)-1,0);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "接收失败";
            END(-1);
        }
        buffer[n] = 0;
        getdata = buffer;
        LOG(LogLevel::INFO) << "接收到数据：" << n << "字节";
    }

    virtual void Send(string data) override
    {
        if(current_client_fd<0)
        {
            LOG(LogLevel::ERROR) << "未连接客户端";
            return;
        }
        int n = send(current_client_fd, data.c_str(), data.size(), 0);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "发送失败";
            END(-1);
        }
    }
    virtual void Close(int fd) override
    {
        close(fd);
    }
    virtual int Cur_rclientfd() override
    {
        return current_client_fd;   
    }
    virtual int Socket_fd() override
    {
        return _sockfd;
    }

private:
    int current_client_fd;
    InterAddr _server;
    uint16_t _port;
    int _sockfd;
};